package cn.mengfly.algorithm.collection.stack;

import java.util.EmptyStackException;
import java.util.Iterator;

/**
 * @author wangp
 */
public class FixedCapacityStack<T> implements Stack<T> {

    /**
     * value array
     */
    private final Object[] ts;
    /**
     * size of stack
     */
    private int size;

    public FixedCapacityStack(int capacity) {
        ts = new Object[capacity];
    }

    @Override
    public void push(T t) {
        if (isFull()) {
            throw new ArrayIndexOutOfBoundsException();
        }
        ts[size++] = t;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T pop() {
        if (isEmpty()) {
            return null;
        }
        final Object t = ts[--size];
        return (T) t;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T peak() {
        if (isEmpty()) {
            throw new EmptyStackException();
        }
        return (T) ts[(size - 1)];
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public void clear() {
        for (int i = 0; i < size; i++) {
            ts[i] = null;
        }
        size = 0;
    }


    public boolean isFull() {
        return size == ts.length;
    }

    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {
            final Object[] elementsOfCopy = ts;

            int curIndex = 0;

            @Override
            public boolean hasNext() {
                return curIndex < elementsOfCopy.length;
            }

            @Override
            public T next() {
                //noinspection unchecked
                return (T) elementsOfCopy[curIndex++];
            }
        };
    }
}
